
from django.forms.utils import pretty_name
from django.http import HttpResponseNotAllowed


class View:

    http_method_names = [
        "get",
        "post",
        "put",
        "patch",
        "delete",
        "head",
        "options",
        "trace",
    ]

    @classmethod
    def as_view(cls, **initkwargs):
        """
        模拟 django 的as_view 方法,返回一个函数
        """
        # 1.参数检查
        for key in initkwargs:
            if key in cls.http_method_names:
                raise TypeError(f"不能使用 HTTP 方法名称{key}作为参数")

        # 2.返回一个函数
        def view(request, *args, **kwargs):
            # 2.1.创建一个类的实例
            self = cls(**initkwargs)

            # 初始化请求属性（模拟setup）
            # 
            self.request = request
            self.args = args
            self.kwargs = kwargs

            # 2.2.调用dispatch方法 分发请求
            if request.method.lower() in self.http_method_names:
                # getattr(object, name, defalut) 尝试获取object对象的name属性，如果不存在，返回defalut
                # requst.method GET get
                handler = getattr(self, request.method.lower(), None)
                if handler:
                    #  self.get()
                    return handler(request, *args, **kwargs)
                # 2.3.如果请求方法不在http_method_names中，返回405
                # return HttpResponseNotAllowed(cls.http_method_names)
        return view
     

# 使用示例
class MyView(View):
    see = "hello"

    def __init__(self, **initkwargs):
        for key, value in initkwargs.items():
            setattr(self, key, value)  # 设置实例属性，例如self.see

    def get(self, request):
        return f"{self.see} GET 请求"

    def post(self, request):
        return f"{self.see} POST 请求"

# 模拟路由
url_patterns = {
    '/test':MyView.as_view(see="你好")
}

# 模拟请求
def handle_request(path, method="GET"):
    view = url_patterns.get(path)
    # view 已经接受了一个返回的view 函数
    if view:
        # 请求之前的操作
        class Request:
            def __init__(self, method):
                self.method = method
        # <function View.as_view.<locals>.view at 0x100ad4400>
        #执行登录操作
        # 执行其他中间件操作
        return view(Request(method))
    return "404 Not Found"

# print(handle_request('/test', "GET"))
# print(handle_request('/test', "POST"))

class Counter:
    def __init__(self):
        self.count = 0
    # __call__ 方法

    # 当类中定义了一个__call__方法时，该类的实例可以像函数一样被调用
    def __call__(self):
       # 每次调用实例的时候，次数+1
       self.count += 1
       return self.count

# 创建一个实例
counter = Counter()
# 普通类调用，会直接返回类的本身
print(counter)
print(counter())
print(counter())
print(counter())